/*
       Licensed to the Apache Software Foundation (ASF) under one
       or more contributor license agreements.  See the NOTICE file
       distributed with this work for additional information
       regarding copyright ownership.  The ASF licenses this file
       to you under the Apache License, Version 2.0 (the
       "License"); you may not use this file except in compliance
       with the License.  You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

       Unless required by applicable law or agreed to in writing,
       software distributed under the License is distributed on an
       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
       KIND, either express or implied.  See the License for the
       specific language governing permissions and limitations
       under the License.
*/
package com.wondertek.mist.plugins;

import java.net.URLDecoder;

import org.apache.cordova.CordovaWebView;
import org.apache.cordova.api.CallbackContext;
import org.apache.cordova.api.CordovaPlugin;
import org.apache.cordova.api.LOG;
import org.apache.cordova.api.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.net.Uri;
import android.util.Log;
import android.util.TypedValue;
import android.view.Window;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.webkit.JavascriptInterface;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebStorage;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.LinearLayout;

@SuppressLint({ "SetJavaScriptEnabled", "NewApi" })
public class JSWebViewPlugin extends CordovaPlugin {

    protected static final String LOG_TAG = "InAppBrowser";

    private static final String EXIT_EVENT = "exit";
    private static final String LOAD_START_EVENT = "loadstart";
    private static final String LOAD_STOP_EVENT = "loadstop";
    private long MAX_QUOTA = 100 * 1024 * 1024;

    private Dialog dialog;
    private WebView inAppWebView;

    private CallbackContext callbackContext;
    

    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        PluginResult.Status status = PluginResult.Status.OK;
        String result = "";
        this.callbackContext = callbackContext;
        
        
        try {
        	 JSONObject json = (JSONObject) args.getJSONObject(0);
     		
     		
            if (action.equals("open")) {
            	String url=json.getString("url");
              
                url = updateUrl(url);
                showWebPage(url);
               
            }
            else if (action.equals("close")) {
                closeDialog();

                PluginResult pluginResult = new PluginResult(PluginResult.Status.OK);
                pluginResult.setKeepCallback(false);
                this.callbackContext.sendPluginResult(pluginResult);
            }
            else {
                status = PluginResult.Status.INVALID_ACTION;
            }
            PluginResult pluginResult = new PluginResult(status, result);
            pluginResult.setKeepCallback(true);
            this.callbackContext.sendPluginResult(pluginResult);
        } catch (JSONException e) {
            this.callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
        }
        return true;
    }

    private Object jsInterface=new Object(){
    	@JavascriptInterface
		public void back(String param){
    		
    		JSWebViewPlugin.this.webView.loadUrl("javascript:if(window.handleWebViewBack){window.handleWebViewBack('"+(param==null?"":param)+"')};");
    		closeDialog();
		}
		@JavascriptInterface
		public void share(String param){
			
			try {
				//兼容IOS的写法
				String[]  args = URLDecoder.decode(param,"UTF-8").split("\\|");
				String json= "[{title:\""+args[0]+"\",text:\""+args[1]+"\",url:\""+args[2]+"\",image:\""+args[3]+"\",media:"+args[4]+"}]";
    			JSWebViewPlugin.this.webView.pluginManager.exec("Share", "share", null,json);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
    };
    
    

    private String updateUrl(String url) {
        Uri newUrl = Uri.parse(url);
        if (newUrl.isRelative()) {
            url = this.webView.getUrl().substring(0, this.webView.getUrl().lastIndexOf("/")+1) + url;
        }
        return url;
    }

    
    
   

    /**
     * Closes the dialog
     */
    private void closeDialog() {
        try {
            JSONObject obj = new JSONObject();
            obj.put("type", EXIT_EVENT);

            sendUpdate(obj, false);
        } catch (JSONException ex) {
            Log.d(LOG_TAG, "Should never happen");
        }
        
        if (dialog != null) {
            dialog.dismiss();
        }
    }

   
    public String showWebPage(final String url) {
       
        
        final CordovaWebView thatWebView = this.webView;

        // Create dialog in new thread
        Runnable runnable = new Runnable() {
            /**
             * Convert our DIP units to Pixels
             *
             * @return int
             */
            private int dpToPixels(int dipValue) {
                int value = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP,
                                                            (float) dipValue,
                                                            cordova.getActivity().getResources().getDisplayMetrics()
                );

                return value;
            }

            @SuppressLint("JavascriptInterface")
            public void run() {
                // Let's create the main dialog
                dialog = new Dialog(cordova.getActivity(), android.R.style.Theme_NoTitleBar);
                dialog.getWindow().getAttributes().windowAnimations = android.R.style.Animation_Dialog;
                dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
                dialog.setCancelable(true);
                dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
                        public void onDismiss(DialogInterface dialog) {
                            try {
                                JSONObject obj = new JSONObject();
                                obj.put("type", EXIT_EVENT);

                                sendUpdate(obj, false);
                            } catch (JSONException e) {
                                Log.d(LOG_TAG, "Should never happen");
                            }
                        }
                });

                // Main container layout
                LinearLayout main = new LinearLayout(cordova.getActivity());
                main.setOrientation(LinearLayout.VERTICAL);

                             // WebView
                inAppWebView = new WebView(cordova.getActivity());
                inAppWebView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
                inAppWebView.setWebChromeClient(new InAppChromeClient());
                WebViewClient client = new InAppBrowserClient(thatWebView);
                inAppWebView.setWebViewClient(client);
                WebSettings settings = inAppWebView.getSettings();
                settings.setJavaScriptEnabled(true);
                settings.setJavaScriptCanOpenWindowsAutomatically(true);
                settings.setBuiltInZoomControls(true);
                /** 
                 * We need to be careful of this line as a future Android release may deprecate it out of existence.
                 * Can't replace it with the API 8 level call right now as our minimum SDK is 7 until May 2013
                 */
                // @TODO: replace with settings.setPluginState(android.webkit.WebSettings.PluginState.ON)
                //settings.setPluginsEnabled(true);
                settings.setPluginState(WebSettings.PluginState.ON);
                settings.setDatabaseEnabled(true);
                String databasePath = cordova.getActivity().getApplicationContext().getDir("inAppBrowserDB", Context.MODE_PRIVATE).getPath();
                settings.setDatabasePath(databasePath);
                settings.setDomStorageEnabled(true);
                
                
                inAppWebView.addJavascriptInterface(jsInterface, "CFUB");
                
                int idv=6;
                inAppWebView.loadUrl(url);
                inAppWebView.setId(idv);
                inAppWebView.getSettings().setLoadWithOverviewMode(true);
                inAppWebView.getSettings().setUseWideViewPort(true);
                inAppWebView.requestFocus();
                inAppWebView.requestFocusFromTouch();

               
                // Add our webview to our main view/layout
                main.addView(inAppWebView);

                LayoutParams lp = new LayoutParams();
                lp.copyFrom(dialog.getWindow().getAttributes());
                lp.width = LayoutParams.MATCH_PARENT;
                lp.height = LayoutParams.MATCH_PARENT;

                dialog.setContentView(main);
                dialog.show();
                dialog.getWindow().setAttributes(lp);
            }
        };
        this.cordova.getActivity().runOnUiThread(runnable);
        return "";
    }

    /**
     * Create a new plugin result and send it back to JavaScript
     *
     * @param obj a JSONObject contain event payload information
     */
    private void sendUpdate(JSONObject obj, boolean keepCallback) {
        PluginResult result = new PluginResult(PluginResult.Status.OK, obj);
        result.setKeepCallback(keepCallback);
        this.callbackContext.sendPluginResult(result);
    }

    public class InAppChromeClient extends WebChromeClient {

     
        @Override
        public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize,
                long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater)
        {
            LOG.d(LOG_TAG, "onExceededDatabaseQuota estimatedSize: %d  currentQuota: %d  totalUsedQuota: %d", estimatedSize, currentQuota, totalUsedQuota);

            if (estimatedSize < MAX_QUOTA)
            {
                //increase for 1Mb
                long newQuota = estimatedSize;
                LOG.d(LOG_TAG, "calling quotaUpdater.updateQuota newQuota: %d", newQuota);
                quotaUpdater.updateQuota(newQuota);
            }
            else
            {
                // Set the quota to whatever it is and force an error
                // TODO: get docs on how to handle this properly
                quotaUpdater.updateQuota(currentQuota);
            }
        }
    }
  
    public class InAppBrowserClient extends WebViewClient {
     
        CordovaWebView webView;


        public InAppBrowserClient(CordovaWebView webView) {
            this.webView = webView;
          
        }

        @Override
        public void onPageStarted(WebView view, String url,  Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
            
        }
        
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            
        }
    }
}
